#include<stdlib.h>
#include "pile.h"

/**  Procedure libererPile
 *   Libère la mémoire occupée par la Pile
 *   La mémoire occupée par la suite d'états est elle auusi libérée
 *   La mémoire correspondant aux états de la suite est libérée
 *   Cette dernière opération est effectuée par une procédure libérerEtat qui doit être fournie
 *   La signature de la procédure  doit être 
 *       void libererEtat(Etat *e);
 *
 *    Arguments 
 *         Pile *p : la pile à libérer
 *
*/


void libererPile(Pile *p) {
  Stack *s=p->sommet, *aux;

  while ( s!= NULL){
    aux = s->suivant;
    libererEtat(s->element);
    free(s);
    s = aux;
  }
  
  free(p);

} 


/**  Fonction  nouvellePile
 *   Crée une nouvelle pile vide
 * 
 *   Retourne:
 *              un pointeur sur la nouvelle pile  
 */



Pile *nouvellePile(void){ 
  Pile *pAux = (Pile *) malloc(sizeof(Pile));

  pAux->HAUTEUR_MAX_PILE= 0;
  pAux->HAUTEUR_EFFECTIVE = 0;
  pAux->sommet = NULL;
  
  
  return pAux ;
 }




/**  Fonction  estVide
 *   Teste si la pile est vide 
 *
 *   Paramètre:
 *              Pile *p: la pile à tester 
 * 
 *   Retourne:
 *              O: si la pile contient au moins un Etat
 *              1: si la pile ne contient aucun Etat
 *
 *
 *   La signature forme de la fonction  est   
 *
 *            int estVide(Pile *p);
 * 
 *   L'implémentation effective est réalisé en utilisant une Macro.
 *   Ceci permet d'économiser un appel de fonction, tout en maintenant l'encapsulation.
 *
 */


//int pileVide(Pile *p){
//  return 0;
// }




/**  Procedure  enpiler
 *   Ajoute un Etat à une Pile
 *
 *   Paramètres:
 *              Pile *p: la pile dans laquelle on veut ajouter un Etat.
 *            
 *              Etat *e: L'Etat à ajouter. 
 * 
 *   
 */

void empiler(Pile *p, Etat *e){
  Stack *sAux= (Stack *) malloc(sizeof(Stack));
  
  sAux->element = e;
  sAux->suivant = p->sommet ;
  

  p->sommet= sAux;
  p->HAUTEUR_EFFECTIVE +=1 ;
  if ( p->HAUTEUR_EFFECTIVE > p->HAUTEUR_MAX_PILE)
    p->HAUTEUR_MAX_PILE = p->HAUTEUR_EFFECTIVE;

}


/**  Fonction  depiler
 *   Retire un Etat dans une pile  
 *
 *   Paramètre:
 *              Pile *p: la pile dont il faut retirer un Etat
 * 
 *   Retourne:
 *              Etat * : l'état retiré
 *
 */



Etat *depiler(Pile *p){
  Stack *sAux = p->sommet;
  Etat *etatAux = sAux->element;
  
  p->sommet =sAux->suivant;
  p->HAUTEUR_EFFECTIVE -=1 ;
  
  free(sAux);

  
  return etatAux;
}


/**  Fonction  hauteurMax
 *   Fournit la hauteur de de la plus haute pile  manipulée lors du calcul
 *
 *   Paramètre:
 *              Pile *p: la pile à étudier
 * 
 *   Retourne:
 *              Un entier : La hauteur recherchée
 *              1: si la pile ne contient aucun Etat
 *
 *
 *   La signature forme de la fonction  est   
 *
 *            int hauteurMax(Pile *p);
 * 
 *   L'implémentation effective est réalisé en utilisant une Macro.
 *   Ceci permet d'économiser un appel de fonction, tout en maintenant l'encapsulation.
 *
 */
 


// int hauteurMax(Pile *p){
//     return (0) ;
//}
